package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Imhistory;
import com.example.onlinemonitoring.model.Imsensor;
import com.example.onlinemonitoring.serviceImpl.ImsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.Date;

/**
 * 智能监控器
 */
@Service("imCom")
@Scope("prototype")
public class ImCom extends CommPortManager {
    @Autowired
    private ImsensorServiceImpl imserviceimpl;

    @Override
    public void receiveData(String str) {
        str = str.toUpperCase();
        setText(str);
        int addr = parseHex4(str.substring(0, 2));
        String content = str.substring(6, 22);
        reSend[addr] = 0;
        addrindex++;
        setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备组：" + ad.getDevicegroup() + " 设备地址：" + addr);
        for (int i = 1; i <= 4; i++) {
            Imsensor im = new Imsensor();
            im.setStationid(ad.getStationid());
            im.setDevicegroup(ad.getDevicegroup());
            im.setDeviceaddr(addr);
            im.setPointaddr(i);
            Imsensor sensor = imserviceimpl.getModel(im);
            if (sensor == null) {
                setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i + " ！ 请先添加该监测点！");
                continue;
            }
            if (sensor.getInuse() == 1) {
                SensorData(im, sensor, parseHex4(content.substring((i - 1) * 4, 4 + (i - 1) * 4)));
            }
        }
    }

    void SensorData(Imsensor im, Imsensor sensor, int value) {
        if (sensor.getLastdenominator() == null) {
            setText("设备地址" + im.getDeviceaddr() + "的监测点" + im.getPointaddr() + " 未设置系数！");
            return;
        }

        float val = value * sensor.getLastdenominator();
        setText(sensor.getPointname() + "：" + val + " " + sensor.getLastunit());
        im.setLastdata(val);
        im.setLastdatatime(new Date());

        im.setLastalarmlevel(GetAlarmStatus(isnull(Math.abs(im.getLastdata())), isnull(sensor.getAlarmvalue()),
                isnull(sensor.getAlarmrelievevalue()), isnull(sensor.getWarnvalue()),
                isnull(sensor.getWarnrelievevalue()),
                isnull(sensor.getLastalarmlevel()), true, sensor.getLastname(), sensor.getDevicegroup(),
                sensor.getDeviceaddr(), sensor.getPointname(), sensor.getPointaddr()));

        // 报警消息
        im.setLastalarmmessage(GetAlarmMessage(im.getLastalarmlevel(), sensor.getLastname()));
        im.setLastcommunicationstatus(0);
        im.setLasthisdatatime(addHistory(sensor));
        if (imserviceimpl.Update(im, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(Imsensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Imsensor sensor) {
        Imhistory his = new Imhistory();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAddrname(sensor.getAddrname());
        his.setPointaddr(sensor.getPointaddr());
        his.setPointname(sensor.getPointname());
        his.setData(sensor.getLastdata());
        his.setDatatime(sensor.getLastdatatime());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDenominator(sensor.getLastdenominator());
        his.setUnit(sensor.getLastunit());
        his.setName(sensor.getLastname());
        imserviceimpl.Add(his);
    }

    // 指定使用beanname为threadPool的线程池
    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {

        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);
                if (reSend[addrindex] > 3) {
                    imserviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }
                reSend[addrindex]++;
            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            Thread.sleep(timersp);
        }
    }
}
